package cn.iocoder.yudao.module.reading.dal.mysql.plan;

import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.reading.dal.dataobject.plan.ReadingPlanDO;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

/**
 * 阅读计划 Mapper
 *
 * @author 芋道源码
 */
@Mapper
public interface ReadingPlanMapper extends BaseMapperX<ReadingPlanDO> {

    /**
     * 根据用户ID查询计划列表
     *
     * @param userId 用户ID
     * @param status 计划状态（可选）
     * @return 计划列表
     */
    default List<ReadingPlanDO> selectByUserId(Long userId, String status) {
        return selectList(new LambdaQueryWrapperX<ReadingPlanDO>()
                .eq(ReadingPlanDO::getUserId, userId)
                .eqIfPresent(ReadingPlanDO::getStatus, status)
                .orderByDesc(ReadingPlanDO::getCreateTime));
    }

    /**
     * 根据用户ID查询进行中的计划
     *
     * @param userId 用户ID
     * @return 计划列表
     */
    default List<ReadingPlanDO> selectActiveByUserId(Long userId) {
        return selectList(new LambdaQueryWrapperX<ReadingPlanDO>()
                .eq(ReadingPlanDO::getUserId, userId)
                .eq(ReadingPlanDO::getStatus, "active")
                .orderByDesc(ReadingPlanDO::getCreateTime));
    }

    /**
     * 根据用户ID和计划名称查询计划
     *
     * @param userId   用户ID
     * @param planName 计划名称
     * @return 计划
     */
    default ReadingPlanDO selectByUserIdAndName(Long userId, String planName) {
        return selectOne(new LambdaQueryWrapperX<ReadingPlanDO>()
                .eq(ReadingPlanDO::getUserId, userId)
                .eq(ReadingPlanDO::getPlanName, planName));
    }

    /**
     * 根据用户ID和计划名称查询有效计划（排除已取消和已删除的计划）
     * 用于创建计划时检查名称重复
     *
     * @param userId   用户ID
     * @param planName 计划名称
     * @return 计划
     */
    default ReadingPlanDO selectActiveByUserIdAndName(Long userId, String planName) {
        return selectOne(new LambdaQueryWrapperX<ReadingPlanDO>()
                .eq(ReadingPlanDO::getUserId, userId)
                .eq(ReadingPlanDO::getPlanName, planName)
                .ne(ReadingPlanDO::getStatus, "cancelled")); // 排除已取消的计划
    }

}
